﻿using BJ.AuthDomain.IService;
using Mapster;
using BJ.AuthEntity.Models;
using BJ.AuthEntity.ViewModels;
using Syspetro.Core.AppDeal;
using Syspetro.Core.DbAccessor;
using Syspetro.Deploy.FreeSqlDb;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Syspetro.Core.Encrypt;
using Syspetro.Core.CommandBus;
using Microsoft.AspNetCore.Http;

namespace BJ.AuthDomain.Service
{
    public class UserService : EntityBaseService<User>, IUserService
    {
        readonly IFreeSql _freeSql;
        readonly IRepository<User> repository;
        readonly ICommandBus _command;
        readonly IHttpContextAccessor _httpContextAccessor;
        public UserService(IFreeSql freeSql, ICommandBus command, IHttpContextAccessor httpContextAccessor)
        {
            _freeSql = freeSql;
            _command = command;
            _httpContextAccessor = httpContextAccessor;

            this.repository = new FreeSqlRepository<User>(freeSql);
        }
        public override IRepository<User> Repository
        {
            get
            {
                return repository;
            }
        }

        public async Task<Guid> AddUserAsync(VM_User_Add user_Add)
        {
            var pswd = _command.Send(new PswdMd5Command { Pswd = user_Add.Password });
            if (!pswd.Success)
                return Guid.Empty;

            var user = user_Add.Adapt<User>();
            var auth = new UserAuth
            {
                Account = user_Add.AuthName,
                Password = pswd.Get().Data,
                Id = user.Id
            };
            Repository.AddTrans(user);
            Repository.AddTrans(auth);
            var i = await Repository.SaveAsync;
            return i > 0 ? user.Id : Guid.Empty;
        }

        public Task<int> AddUsersAsync(List<VM_User_Add> user_Adds)
        {
            foreach (var user_Add in user_Adds)
            {
                var pswd = _command.Send(new PswdMd5Command { Pswd = user_Add.Password });
                var user = user_Add.Adapt<User>();
                var auth = new UserAuth
                {
                    Account = user_Add.AuthName,
                    Password = pswd.Get().Data,
                    Id = user.Id
                };
                Repository.AddTrans(user);
                Repository.AddTrans(auth);
            }
            return Repository.SaveAsync;
        }

        public async Task<VM_User> GetUserFull(Guid id)
        {
            var user = await _freeSql.Select<User>().Include(t => t.Auth).Where(t => t.Id == id).FirstAsync();
            return user.Adapt<VM_User>();
        }

        public async Task<VM_User> UserSearch(VM_User_Search search)
        {
            User user = search.SearchType switch
            {
                AuthEntity.SearchType.Email => await _freeSql.Select<User>().Where(t => t.Emil == search.Name).FirstAsync(),
                AuthEntity.SearchType.SMS => await _freeSql.Select<User>().Where(t => t.Phone == search.Name).FirstAsync(),
                _ => await _freeSql.Select<User>().Include(t => t.Auth).Where(t => t.Auth.Account == search.Name).FirstAsync(),
            };
            return user.Adapt<VM_User>();
        }

        public async Task<PageList<VM_User>> FindUsersFull(VM_User_PageReq pageReq)
        {
            var users = await _freeSql.Select<User>()
                .Where(pageReq.GetWhereExpression())
                .OrderByPropertyName(pageReq.OrderBy, pageReq.IsAscending())
                .Count(out var _total)
                .Page(pageReq.Current, pageReq.Size)
                .ToListAsync();
            return new PageList<VM_User>
            {
                Size = pageReq.Size,
                Current = pageReq.Current,
                Total = _total,
                Records = users.Adapt<List<VM_User>>()
            };
        }

        public Task<bool> Verify(string account)
        {
            return _freeSql.Select<UserAuth>().AnyAsync(t => t.Account == account);
        }

        public async Task<long> GetUserCount()
        {
            return await _freeSql.Select<UserAuth>().CountAsync();
        }
        public async Task<PageList<VM_UserMis>> GetUserList(VM_User_Page pageReq)
        {
            var users = await _freeSql.Select<User>()
                .InnerJoin(d => d.Id == d.Auth.Id)
                .WhereIf(!string.IsNullOrWhiteSpace(pageReq.Account), d => pageReq.Account.Contains(d.Auth.Account))
                .WhereIf(!string.IsNullOrWhiteSpace(pageReq.ID), d => pageReq.ID.ToLower().Contains(d.Id.ToString().ToLower()))
                .OrderByDescending(d => d.Auth.RegisterTime)
                .Count(out var _total)
                .Page(pageReq.Current, pageReq.Size)
                .ToListAsync(a => new
                {
                    AccountType = a.Auth.AccountType,
                    Account = a.Auth.Account,
                    UserName = a.Name,
                    Id = a.Auth.Id,
                    LoginTime = a.Auth.LoginTime,
                    RegisterTime = a.Auth.RegisterTime,
                    Enable=a.Auth.Enable



                });
            return new PageList<VM_UserMis>
            {
                Size = pageReq.Size,
                Current = pageReq.Current,
                Total = _total,
                Records = users.Adapt<List<VM_UserMis>>()
            };
        }
    }
}
